package com.example.spindrift.service;

import com.example.spindrift.dao.SysFileMapper;
import com.example.spindrift.models.SysFile;
import com.example.spindrift.service.Util.MP3Analysis;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.UnsupportedTagException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class FileService {
    @Value("${file.music.savePath}")
    private String musicSavePath; // 音乐保存位置
    @Value("${file.image.savePath}")
    private String imageSavePath; // 图片保存位置
    @Value("${file.lrc.savePath}")
    private String lrcSavePath; // 歌词保存位置
    @Value("${file.rest.savePath}")
    private String defSavePath; // 其他文件保存位置

    @Resource
    SysFileMapper sysFileMapper;

    public List<SysFile> getAllFile(){
        return sysFileMapper.getAllFile();
    }
    public List<SysFile> getFileByName(String fileName){
        return sysFileMapper.getFileByName(fileName);
    }
    public SysFile getFileById(Integer fileId){
        return sysFileMapper.getFileById(fileId);
    }
    public List<SysFile> getFileByType(String typeName){
        return sysFileMapper.getFileByType(typeName);
    }
    public List<SysFile> searchFile(String keyword){
        return sysFileMapper.searchFile(keyword);
    }
    public Integer insertFile(SysFile file){
        return sysFileMapper.insertFile(file);
    }
    public Integer updateFile(SysFile file){
        return sysFileMapper.updateFile(file);
    }
    public Integer deleteFile(Integer fileId){
        return sysFileMapper.deleteFile(fileId);
    }
    public HashMap<String,Object> saveMusic(MultipartFile music){
        SysFile musicFile;
        SysFile imageFile = null;
        File mus = null;
        HashMap<String,Object> data = new HashMap<>();
        try {
            mus = File.createTempFile("lsFile",".mp3");
            music.transferTo(mus);
            // 解析mp3歌曲内容
            MP3Analysis.Mp3Mate mate = MP3Analysis.getMP3Mate(mus);
            // 保存专辑图片
            if(mate.getAlbumImage() != null && mate.getAlbumImage().length > 0){
                imageFile = saveFile(mate.getAlbumImage(),".jpeg");
            }
            // 保存歌曲文件
            musicFile = saveFile(mus);
            data.put("music",musicFile);
            data.put("image",imageFile);
            data.put("mate",mate);
        } catch (IOException | InvalidDataException | UnsupportedTagException e) {
            e.printStackTrace();
        } finally {
            if(mus != null){
                mus.deleteOnExit();
            }
        }
        return data;
    }
    /**
     * 文件保存
     * @param file
     * @param fileType
     * @return
     */
    public SysFile saveFile(byte[] file,String fileType){
        String fileName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + fileType;
        ByteArrayInputStream input = new ByteArrayInputStream(file);
        Integer fileSize = file.length / 1024;
        return save(input,fileType,fileName,fileSize);
    }
    public SysFile saveFile(MultipartFile file){
        InputStream stream = null;
        try {
             stream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String fileName = null;
        try {
            fileName = new String(file.getOriginalFilename().getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String fileType = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
        Integer fileSize = Math.toIntExact(file.getSize());
        return save(stream,fileType,fileName,fileSize);
    }
    public SysFile saveFile(File file){
        String fileName = file.getName();
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        InputStream fileStream;
        try {
            fileStream = new FileInputStream(file);
            return save(fileStream,fileType,fileName, (int) file.length());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
    private SysFile save(InputStream fileStream,String fileType,String fileName,Integer fileSize){
        SysFile fi = new SysFile();
        String url = "";
        String fileSavePath;
        String newFileName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + fileType;
        switch(fileType){
            case ".mp3":
                fileSavePath = musicSavePath;
                url = "/musics/";
                fi.file_type = "music";
                break;
            case ".jpg":
            case ".png":
            case ".jpeg":
                fileSavePath = imageSavePath;
                url = "/images/";
                fi.file_type = "image";
                break;
            case ".lrc":
                fileSavePath = lrcSavePath;
                url = "/lrcs/";
                fi.file_type = "lrc";
                break;
            default:
                fileSavePath = defSavePath;
                url = "/rests/";
                fi.file_type = "rest";
                break;
        }
        fileSavePath = fileSavePath + newFileName;
        byte[] bt = new byte[1024];
        int len = 0;
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(fileSavePath);
            while ((len = fileStream.read(bt)) != -1){
                output.write(bt,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(output != null)
                    output.close();
                if(fileStream != null)
                    fileStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        fi.file_name = newFileName;
        fi.url = url + newFileName;
        fi.physice_url = fileSavePath;
        fi.size = fileSize;
        fi.upload_time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        fi.suffix = fileType;
        // 将文件信息存储到数据库
        sysFileMapper.insertFile(fi);
        return sysFileMapper.getFileById(fi.file_id);
    }
}
